package com.photoeditor.demo.ui.adapter.effect;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.support.v4.view.PagerAdapter;
import android.text.TextUtils;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.common.base.ComponentContext;
import com.common.base.log.RLog;
import com.common.base.utils.thread.ThreadPool;
import com.photoeditor.R;
import com.photoeditor.demo.imageloader.GlideApp;
import com.photoeditor.demo.model.bean.IItemBean;
import com.photoeditor.demo.model.bean.StoreOnlineItemBean;
import com.photoeditor.demo.model.store.module.StoreOnlineBean;
import com.photoeditor.demo.ui.widget.RenderingView;
import com.photoeditor.demo.util.APKAssertImageLoader;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by Administrator on 2017/5/11 0011.
 */

public class FilterDetailPagerAdapter extends PagerAdapter {
    private static final String TAG = FilterDetailPagerAdapter.class.getName();

    private Activity mContext;
    private ArrayList<StoreOnlineBean> mDatas;
    private SparseBooleanArray mMap = new SparseBooleanArray();
    private SparseArray<ImageView> viewMap = new SparseArray<>();
    private CopyOnWriteArrayList<View> mCacheView = new CopyOnWriteArrayList<>();
    private Map<StoreOnlineBean, Integer> mUpdateDataPosition = new HashMap<>();
    private int mForceRefreshCount;

    private boolean mLoadAssert;

    private Resources mResources;

    public void setListener(StartBlurListener mListener) {
        this.mListener = mListener;
    }

    private StartBlurListener mListener;

    public FilterDetailPagerAdapter(Activity mContext, ArrayList<StoreOnlineBean> mDatas, boolean loadAssert, String pkName) {
        this.mContext = mContext;
        this.mDatas = mDatas;
        mForceRefreshCount = 0;
        mLoadAssert = loadAssert;
        if (mLoadAssert && !TextUtils.isEmpty(pkName)) {
            try {
                mResources = ComponentContext.getContext().createPackageContext(pkName, Context.CONTEXT_IGNORE_SECURITY).getResources();
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public int getCount() {
        return mDatas.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        StoreOnlineBean storeOnlineBean = mDatas.get(position);
        View contentView = null;
        contentView = LayoutInflater.from(mContext).inflate(R.layout.item_category_detail_image, null);
        RenderingView renderingView = (RenderingView) contentView.findViewById(R.id.iv_filter_preview);
        //  既然view每次都是重新new出来的，那旧只记录最新的
        viewMap.put(position, renderingView);

        String topPreview = storeOnlineBean.getPreview();
        String bottomPreview = "";
        if (topPreview != null) {
            String[] split = topPreview.split("#");
            if (split.length > 1) {
                if (mLoadAssert && mResources != null) {
                    String rootUrl = StoreOnlineBean.removeQueryString(storeOnlineBean.getRootUrl());
                    topPreview = StoreOnlineBean.removeQueryString(split[0]).substring(rootUrl == null ? 0 : rootUrl.length() + 1);
                    bottomPreview = StoreOnlineBean.removeQueryString(split[1]).substring(rootUrl == null ? 0 : rootUrl.length() + 1);
                    loadAssertTopImage(topPreview, renderingView, position);
                    loadAssertBottomImage(bottomPreview, renderingView);
                } else {
                    topPreview = split[0];
                    bottomPreview = split[1];
                    loadTopImage(topPreview, renderingView, position, 0);
                    loadBottomImage(bottomPreview, renderingView, 0);
                }
            } else if (split.length == 1) {
                if (mLoadAssert && mResources != null) {
                    String rootUrl = StoreOnlineBean.removeQueryString(storeOnlineBean.getRootUrl());
                    bottomPreview = StoreOnlineBean.removeQueryString(split[1]).substring(rootUrl == null ? 0 : rootUrl.length() + 1);
                    loadAssertTopImage(bottomPreview, renderingView, position);
                    loadAssertBottomImage(bottomPreview, renderingView);
                } else {
                    bottomPreview = split[0];
                    loadTopImage(bottomPreview, renderingView, position, 0);
                    loadBottomImage(bottomPreview, renderingView, 0);
                }
            }
        }
        if (contentView != null) {
            container.addView(contentView);
            contentView.setTag(storeOnlineBean);
        }
        return contentView;
    }

    private static final int LOAD_IMAGE_MAXIMUM_REDIRECTS = 3;// 加载图片最大重试次数

    private void loadTopImage(final String preview, final RenderingView view, final int position, final int redirects) {
        if (view == null) {
            return;
        }
        if (redirects >= LOAD_IMAGE_MAXIMUM_REDIRECTS) {
            RLog.v(TAG, "category detail: load top image faild tetry reach max value");
            return;
        }
        if (mContext == null || mContext.isDestroyed()) {
            return;
        }

        GlideApp.with(mContext)
                .asBitmap()
                .skipMemoryCache(true)
                .load(preview)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                        if (view != null) {
                            view.setTopImage(resource);
                        }
                        if (!mMap.get(position, false)) {
                            mMap.put(position, true);
                        }
                        if (mListener != null) {
                            mListener.blur(position, true);
                        }
                    }

                    @Override
                    public void onLoadFailed(Drawable errorDrawable) {
                        // 这里需要runUITask处理，目的是通过post一个handler，因为新版本中不能再onLoadFailed中做跟glide有关的事情
                        // 而且需要clear，新版本的glide如果发现into的是同一个，会复用旧的，导致redirects始终是旧值
                        final SimpleTarget<Bitmap> target = this;
                        ThreadPool.runUITask(new Runnable() {
                            @Override
                            public void run() {
                                if (mContext == null || mContext.isDestroyed()) {
                                    return;
                                }
                                try {
                                    GlideApp.with(mContext).clear(target);
                                } catch (Exception e) {
                                }
                                loadTopImage(preview, view, position, redirects + 1);
                            }
                        });
                    }
                });
    }

    private void loadBottomImage(final String preview, final RenderingView view, final int redirects) {
        if (view == null) {
            return;
        }
        if (redirects >= LOAD_IMAGE_MAXIMUM_REDIRECTS) {
            RLog.v(TAG, "category detail: load bottom image faild tetry reach max value");
            return;
        }

        if (mContext == null || mContext.isDestroyed()) {
            return;
        }

        GlideApp.with(mContext)
                .asBitmap()
                .skipMemoryCache(true)
                .load(preview)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                        if (view != null) {
                            view.setBottomImage(resource);
                        }
                    }

                    @Override
                    public void onLoadFailed(Drawable errorDrawable) {
                        // 这里需要runUITask处理，目的是通过post一个handler，因为新版本中不能再onLoadFailed中做跟glide有关的事情
                        // 而且需要clear，新版本的glide如果发现into的是同一个，会复用旧的，导致redirects始终是旧值
                        final SimpleTarget<Bitmap> target = this;
                        ThreadPool.runUITask(new Runnable() {
                            @Override
                            public void run() {
                                if (mContext == null || mContext.isDestroyed()) {
                                    return;
                                }
                                try {
                                    GlideApp.with(mContext).clear(target);
                                } catch (Exception e) {

                                }
                                loadBottomImage(preview, view, redirects + 1);
                            }
                        });

                    }
                });
    }

    private void loadAssertTopImage(final String preview, final RenderingView view, final int position) {
        if (view == null) {
            return;
        }

        APKAssertImageLoader.with(mResources).load(preview).into(new APKAssertImageLoader.OnLoadListener() {
            @Override
            public void onLoadSuccess(Bitmap bitmap) {
                view.setTopImage(bitmap);
                if (!mMap.get(position, false)) {
                    mMap.put(position, true);
                }
                if (mListener != null) {
                    mListener.blur(position, true);
                }
            }

            @Override
            public void onLoadFail() {
            }
        });
    }

    private void loadAssertBottomImage(final String preview, final RenderingView view) {
        if (view == null) {
            return;
        }
        APKAssertImageLoader.with(mResources).load(preview).into(new APKAssertImageLoader.OnLoadListener() {
            @Override
            public void onLoadSuccess(Bitmap bitmap) {
                view.setBottomImage(bitmap);
            }

            @Override
            public void onLoadFail() {
            }
        });
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        View oldView = (View) object;
        container.removeView(oldView);
    }

    public View getCacheView(IItemBean itemBean) {
        int index = 0;
        for (int i = 0; i < mCacheView.size(); i++) {
            View view = mCacheView.get(i);
            if (itemBean instanceof StoreOnlineItemBean) {
                if (view instanceof ImageView) {
                    index = i;
                    break;
                }
            }
        }
        if (index >= 0 && index < mCacheView.size()) {
            return mCacheView.remove(index);
        }
        return null;
    }

    @Override
    public int getItemPosition(Object object) {
        if (mUpdateDataPosition.size() > 0) {
            View view = (View) object;
            int position = super.getItemPosition(object);
            Object tag = view.getTag();
            if (tag instanceof IItemBean) {
                Integer obj = mUpdateDataPosition.remove(tag);
                if (obj != null) {
                    position = obj;
                }
            }
            return position;
        } else if (mForceRefreshCount > 0) {
            mForceRefreshCount--;
            return POSITION_NONE;
        }
        return super.getItemPosition(object);
    }


    public void setData(ArrayList<StoreOnlineBean> datas) {
        mDatas = datas;
        mForceRefreshCount = mDatas.size();
        notifyDataSetChanged();
    }

    public void addData(int index, StoreOnlineBean data) {
        if (index < 0) {
            index = 0;
        } else if (index > mDatas.size()) {
            index = mDatas.size();
        }
        mUpdateDataPosition.put(data, POSITION_NONE);
        for (int i = index; i < mDatas.size(); i++) {
            mUpdateDataPosition.put(mDatas.get(i), i + 1);
        }
        mDatas.add(index, data);
        notifyDataSetChanged();
    }

    public boolean isResReady(int position) {
        return mMap.get(position, false);
    }

    public ImageView getCurrentView(int position) {
        return viewMap.get(position);
    }

    public interface StartBlurListener {
        void blur(int position, boolean ready);
    }
}
